
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { refreshTokenApi } from '@/api/index';
import { storage } from '@/utils/storage';

// 扩展AxiosRequestConfig接口以支持_retry属性
interface ExtendedAxiosRequestConfig extends AxiosRequestConfig {
  _retry?: boolean;
}

// 自定义JSON解析器，处理长整数精度丢失问题
const parseJSONWithBigInt = (text: string) => {
  // 先预处理JSON字符串，将长整数转换为字符串格式
  // 匹配可能导致精度丢失的长整数（16位以上的纯数字）
  const processedText = text.replace(/(:\s*)(\d{16,})(?=\s*[,}\]])/g, '$1"$2"');
  
  return JSON.parse(processedText, (key, value) => {
    // 检查是否为数字字符串且长度超过15位（JavaScript安全整数范围）
    if (typeof value === 'string' && /^\d{16,}$/.test(value)) {
      return value; // 保持为字符串，避免精度丢失
    }
    // 检查是否为超出安全范围的数字
    if (typeof value === 'number' && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER)) {
      return value.toString(); // 转换为字符串
    }
    return value;
  });
};

// 创建axios实例
const axiosInstance = axios.create({
  timeout: 10000, // 10秒超时
  withCredentials: true, // 允许携带cookie
  // 自定义响应数据转换
  transformResponse: [(data) => {
    if (typeof data === 'string') {
      try {
        return parseJSONWithBigInt(data);
      } catch (e) {
        return data;
      }
    }
    return data;
  }],
});

// token刷新相关状态管理
let isRefreshing = false; // 是否正在刷新token
let failedQueue: Array<{
  resolve: (value?: any) => void; // 用于请求成功时调用
  reject: (reason?: any) => void;  // 用于请求失败时调用
}> = []; // 失败请求队列

// 处理队列中的请求
const processQueue = (error: any, token: string | null = null) => {
  console.log(`处理队列中的${failedQueue.length}个请求，token:`, token ? '存在' : '不存在', 'error:', error ? error.message : '无');
  
  failedQueue.forEach(({ resolve, reject }) => {
    if (error) {
      reject(error); // 所有等待的请求都失败
    } else {
      resolve(token);// 所有等待的请求都继续执行
    }
  });
  
  failedQueue = [];
  console.log('队列处理完成，已清空队列');
};

// 统一的token刷新处理函数
const handleTokenRefresh = async (originalRequest: ExtendedAxiosRequestConfig): Promise<any> => {
  console.log('开始token刷新流程');
  
  // 避免无限循环
  if (originalRequest._retry) {
    console.log('请求已重试过，直接返回401错误');
    throw new Error('Token无效或已过期');
  }
  
  // 标记当前请求已重试
  originalRequest._retry = true;
  
  // 如果当前正在刷新token，将请求加入队列
  if (isRefreshing) {
    console.log('token正在刷新中，将请求加入队列');
    return new Promise((resolve, reject) => {
      failedQueue.push({ resolve, reject });
    }).then(() => {
      console.log('队列中的请求被重新执行');
      return axiosInstance(originalRequest);
    }).catch(err => {
      console.error('队列中的请求执行失败:', err);
      return Promise.reject(err);
    });
  }
  
  // 开始刷新token
  isRefreshing = true;
  console.log('开始刷新token');
  
  try {
    // 调用刷新token接口
    const refreshResponse = await refreshTokenApi();
    console.log('token刷新成功:', refreshResponse);
    
    // 从响应中获取新的accessToken和refreshToken
    const newAccessToken = refreshResponse.data?.accessToken;
    const newRefreshToken = refreshResponse.data?.refreshToken;
    
    if (newAccessToken) {
      // 更新token存储
      storage.setItem('accessToken', newAccessToken);
      console.log('新的accessToken已保存到localStorage');
      
      // 如果有新的refreshToken也更新
      if (newRefreshToken) {
        storage.setItem('refreshToken', newRefreshToken);
        console.log('新的refreshToken已保存到localStorage');
      }
      
      // 更新原始请求的Authorization头
      if (!originalRequest.headers) {
        originalRequest.headers = {};
      }
      originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
      
      // 处理队列中的请求
      processQueue(null, newAccessToken);
      
      // 重新发送原始请求
      console.log('重新发送原始请求');
      return axiosInstance(originalRequest);
    } else {
      throw new Error('刷新响应中未找到accessToken');
    }
  } catch (refreshError) {
    console.error('token刷新失败:', refreshError);
    
    // 处理队列中的请求（传递错误）
    processQueue(refreshError, null);
    
    // 清除存储的token
    storage.removeItem('accessToken');
    storage.removeItem('refreshToken');
    
    // 跳转到登录页，并保存当前路由
    const currentPath = window.location.hash.slice(1); // 去掉#号
    if (currentPath !== '/login') {
      window.location.href = `/#/login?redirect=${encodeURIComponent(currentPath)}`;
    }
    
    return Promise.reject(refreshError);
  } finally {
    isRefreshing = false;
    console.log('token刷新流程结束');
  }
};

// 请求拦截器 - 自动添加token
axiosInstance.interceptors.request.use(
  (config) => {
    // 动态设置Content-Type：当为FormData时让浏览器自动设置multipart边界；非FormData则使用application/json
    try {
      const isFormData = typeof FormData !== 'undefined' && config.data instanceof FormData;
      if (isFormData) {
        if (config.headers) {
          // 删除json默认头，避免覆盖浏览器自动设置的multipart边界
          delete (config.headers as any)['Content-Type'];
        }
      } else {
        // 非FormData按json处理
        if (config.headers) {
          (config.headers as any)['Content-Type'] = 'application/json';
        } else {
          (config as any).headers = { 'Content-Type': 'application/json' };
        }
      }
    } catch (e) {
      // 安全兜底，不影响后续流程
    }

    const token = storage.getItem('accessToken');
    console.log('请求拦截器 - 当前token:', token ? '存在' : '不存在');
    console.log('请求URL:', config.url);
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
      console.log('已添加Authorization头');
    }
    return config;
  }
);

// 响应拦截器 - 统一处理响应和token刷新
axiosInstance.interceptors.response.use(
  async (response: AxiosResponse) => {
    console.log('响应拦截器 - 成功响应:', response.status, response.config.url);
    
    // 对于blob类型的响应，返回完整的response对象
    if (response.config.responseType === 'blob') {
      return response;
    }
    
    // 检查响应数据中的code字段，处理业务层面的401错误
    if (response.data && response.data.code === 401) {
      console.log('检测到响应数据中的401错误，开始token刷新流程');
      
      const originalRequest = response.config as ExtendedAxiosRequestConfig;
      return handleTokenRefresh(originalRequest);
    }
    
    // 其他情况直接返回响应数据
    return response.data;
  },
  async (error) => {
    console.log('响应拦截器捕获错误:', error);
    console.log('错误状态码:', error.response?.status);
    console.log('错误响应数据:', error.response?.data);
    
    const originalRequest = error.config as ExtendedAxiosRequestConfig;
    
    // 统一处理所有类型的401错误（HTTP状态码401或业务状态码401）
    if ((error.response?.status === 401 || error.response?.data?.code === 401) && !originalRequest._retry) {
      console.log('检测到401错误，开始token刷新流程');
      return handleTokenRefresh(originalRequest);
    }
    
    console.error('请求失败:', error);
    
    // 处理其他错误状态
    if (error.response) {
      const { status, data } = error.response;
      switch (status) {
        case 403:
          console.error('权限不足');
          break;
        case 404:
          console.error('请求的资源不存在');
          break;
        case 500:
          console.error('服务器内部错误');
          break;
        default:
          console.error(`请求错误: ${status}`);
      }
      throw new Error(data?.message || `HTTP error! status: ${status}`);
    } else if (error.request) {
      // 网络错误
      console.error('网络错误:', error.request);
      throw new Error('网络连接失败，请检查网络设置');
    } else {
      // 其他错误
      console.error('请求配置错误:', error.message);
      throw error;
    }
  }
);

// 通用请求函数 - 保持与原有接口兼容
export const request = async (url: string, options: AxiosRequestConfig = {}): Promise<any> => {
  try {
    console.log('request函数被调用:', url, options);
    // 确保method是小写，axios要求method必须是小写
    if (options.method) {
      options.method = options.method.toLowerCase() as any;
    }
    const response = await axiosInstance({
      url,
      ...options,
    });
    console.log('request函数响应:', response);
    return response;
  } catch (error) {
    console.error('request函数错误:', error);
    throw error;
  }
};



// 从cookie中获取refreshToken的函数
export const getRefreshTokenFromCookie = (): string | null => {
  try {
    console.log('getRefreshTokenFromCookie: 开始从cookie获取refreshToken');
    console.log('当前cookie:', document.cookie);
    
    // 首先尝试从cookie中获取
    const cookies = document.cookie.split(';');
    for (let cookie of cookies) {
      const [name, value] = cookie.trim().split('=');
      if (name === 'refreshToken') {
        console.log('getRefreshTokenFromCookie: 从cookie中找到refreshToken');
        return decodeURIComponent(value);
      }
    }
    
    // 如果cookie中没有，尝试从隔离存储获取（备用方案）
    const localRefreshToken = storage.getItem('refreshToken');
    if (localRefreshToken) {
      console.log('getRefreshTokenFromCookie: 从localStorage中找到refreshToken');
      return localRefreshToken;
    }
    
    console.log('getRefreshTokenFromCookie: 未找到refreshToken');
    return null;
  } catch (error) {
    console.error('getRefreshTokenFromCookie: 获取refreshToken时出错:', error);
    return null;
  }
};

// API基础配置 - 根据环境动态设置
// 开发环境：使用 /api 前缀配合 vite 代理
// 生产环境：直接使用空字符串，避免多余的 /api 前缀
export const API_BASE_URL = import.meta.env.DEV ? '/api' : '';

// 导出axios实例和相关函数
export { axiosInstance as default};